package com.atguigu.exam.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.exam.entity.PaperQuestion;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.entity.QuestionAnswer;
import com.atguigu.exam.entity.QuestionChoice;
import com.atguigu.exam.mapper.PaperQuestionMapper;
import com.atguigu.exam.mapper.QuestionAnswerMapper;
import com.atguigu.exam.mapper.QuestionChoiceMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.properties.KimiProperties;
import com.atguigu.exam.service.QuestionService;
import com.atguigu.exam.vo.AiGenerateRequestVo;
import com.atguigu.exam.vo.QuestionImportVo;
import com.atguigu.exam.vo.QuestionQueryDto;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 题目Service实现类
 * 实现题目相关的业务逻辑
 */
@Slf4j
@Service
@EnableConfigurationProperties(KimiProperties.class)
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {
    @Autowired
    private QuestionChoiceMapper questionChoiceMapper;
    @Autowired
    private QuestionAnswerMapper questionAnswerMapper;
    @Autowired
    private PaperQuestionMapper paperQuestionMapper;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private KimiProperties kimiProperties;



    @Override
    public Page<Question> getPageByCondition(Page<Question> questionPage, QuestionQueryDto queryDto) {
        //调用QuestionMapper中的分页及带条件查询方法
        Page<Question> questionPage1 = baseMapper.getPageByCondition(questionPage, queryDto);
        return questionPage1;
    }

    @Override
    public Question getQuestionDetailsById(Long id) {
        Question questionDetailsById = baseMapper.getQuestionDetailsById(id);
        //开启一个线程,异步加载统计题目访问次数
        new Thread(() -> {
            //向redis中添加当前题目访问的次数
            redisTemplate.opsForZSet().incrementScore("question:popular", id, 1.0);
        }).start();
        return questionDetailsById;
    }

    @Override
    public void createQuestion(Question question) {
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Question>().eq(Question::getType, question.getType()).eq(Question::getTitle, question.getTitle()));
        if (exists) {
            //抛出异常
            throw new RuntimeException("在<" + question.getType() + ">类型中已经存在该题目，请勿重复添加！");
        }
        baseMapper.insert(question);
        //获取题目的答案
        QuestionAnswer answer = question.getAnswer();
        //获取题目的id
        Long questionId = question.getId();
        //设置答案的关联ID
        answer.setQuestionId(questionId);
        //判断是不是选择题
        if ("CHOICE".equals(question.getType())) {
            //获取题目中选项
            List<QuestionChoice> choices = question.getChoices();
            //创建StringBuilder对象,用于拼接选项内容
            StringBuilder stringBuilder = new StringBuilder();
            //遍历选项
            for (int i = 0; i < choices.size(); i++) {
                //拿到每一个选项
                QuestionChoice questionChoice = choices.get(i);
                //设置选项和关联ID
                questionChoice.setQuestionId(questionId);
                //保存选项
                questionChoiceMapper.insert(questionChoice);
                if (questionChoice.getIsCorrect()) {
                    if (stringBuilder.length() > 0) {
                        stringBuilder.append(",");
                    }
                    stringBuilder.append((char) ('A' + i));
                }
            }
            //将正确答案设置到answer中
            answer.setAnswer(stringBuilder.toString());
        }
        //不是选择题直接保存答案
        questionAnswerMapper.insert(answer);
    }

    //    @Transactional
//    @Override
//    public void createQuestion(Question question) {
//        //判断在当前类型种是否已经存在该题目
//        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Question>().eq(Question::getTitle, question.getTitle()).eq(Question::getType, question.getType()));
//        if (exists){
//            //抛出异常
//            throw new RuntimeException("在<"+question.getType()+">类型中已经存在该题目，请勿重复添加！");
//        }
//        //调用MyBaties-Plus中自带的方法保存题目
//        baseMapper.insert(question);
//        //获取题目的答案
//        QuestionAnswer answer = question.getAnswer();
//        //获取题目的ID
//        Long questionId = question.getId();
//        //设置答案的关联ID
//        answer.setQuestionId(questionId);
//        //如果是选择题就保存选型
//        if ("CHOICE".equals(question.getType())){
//            //获取题目中所有选项
//            List<QuestionChoice> choices = question.getChoices();
//            //创建StringBuilder对象,用于拼接选项内容
//            StringBuilder stringBuilder = new StringBuilder();
//            for (int i = 0; i < choices.size(); i++) {
//                //获取每一个选取
//                QuestionChoice questionChoice = choices.get(i);
//                //设置选项和关联ID
//                questionChoice.setQuestionId(questionId);
//                //如果是选择题保存选项
//                questionChoiceMapper.insert(questionChoice);
//                //判断当前选项是否是正确答案
//                if (questionChoice.getIsCorrect()){
//                    if (stringBuilder.length()>0){
//                        stringBuilder.append(",");
//                    }
//                    stringBuilder.append((char)('A'+i));
//                }
//            }
//            //将正确答案设置到answer中
//            answer.setAnswer(stringBuilder.toString());
//        }
//        //3.保存答案
//        questionAnswerMapper.insert(answer);
//    }

    @Transactional
    @Override
    public void upateQuestion(Question question) {
        //判断更新的题目是否已经在当前类型中存在
        //创建LambdaQueryWrapper对象,用于构建查询条件
        LambdaQueryWrapper<Question> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //封装查询条件
        lambdaQueryWrapper.eq(Question::getType, question.getType())
                .eq(Question::getTitle, question.getTitle())
                .ne(Question::getId, question.getId());
        //调用MyBatis-Plus中自带的查询方法,如果是相同类型和题目标题内容,但id不同,不能更改
        boolean exists = baseMapper.exists(lambdaQueryWrapper);
        if (exists) {
            throw new RuntimeException("在<" + question.getType() + "类型下已经存在该题目,请重新更新为其他题目");
        }
        //不进if,更新该题目
        baseMapper.updateById(question);
        //获取题目的答案
        QuestionAnswer answer = question.getAnswer();
        //如果是选择题,获取题目中选项,传入正确的选项
        if ("CHOICE".equals(question.getType())) {
            //先删除旧的选项
            questionChoiceMapper.delete(new LambdaQueryWrapper<QuestionChoice>().eq(QuestionChoice::getQuestionId, question.getId()));
            //获取题目中选项
            List<QuestionChoice> choices = question.getChoices();
            //创建StringBuilder对象,用于拼接选项内容
            StringBuilder stringBuilder = new StringBuilder();
            //遍历
            for (int i = 0; i < choices.size(); i++) {
                //获取每一个选项
                QuestionChoice questionChoice = choices.get(i);
                //删除旧的选项是逻辑删除,数据库中不会删除,为了更新是id不冲突,创建和更新时间都需要实时更新,所有都设置为null
                questionChoice.setId(null);
                questionChoice.setCreateTime(null);
                questionChoice.setUpdateTime(null);
                //设置选项排序
                questionChoice.setSort(i);
                //保存选择题的答案选项
                questionChoiceMapper.insert(questionChoice);
                if (questionChoice.getIsCorrect()) {
                    if (stringBuilder.length() > 0) {
                        stringBuilder.append(",");
                    }
                    stringBuilder.append((char) ('A' + i));
                }
                answer.setAnswer(stringBuilder.toString());
            }

        }
        //保存答案
        questionAnswerMapper.updateById(answer);
    }
    //添加事务注解,添加事务失败回滚
//    @Transactional
//    @Override
//    public void upateQuestion(Question question) {
//        //判断更新的题目是否已经在当前类型中存在
//        //创建LambdaQueryWrapper对象,用于构建查询条件
//        LambdaQueryWrapper<Question> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        //封装查询条件
//        lambdaQueryWrapper.eq(Question::getType,question.getType())
//                .eq(Question::getTitle,question.getTitle())
//                .ne(Question::getId,question.getId());
//        //调用MyBatis-Plus中自带的查询方法,如果是相同类型和题目标题内容,但id不同,不能更改
//        boolean exists = baseMapper.exists(lambdaQueryWrapper);
//        if (exists){
//            throw new RuntimeException("在<"+question.getType()+"类型下已经存在该题目,请重新更新为其他题目");
//        }
//        //如果不进if,更新该题目
//        baseMapper.updateById(question);
//        //获取题目的答案
//        QuestionAnswer answer = question.getAnswer();
//        if ("CHOICE".equals(question.getType())){
//            //先删除旧选项
//            questionChoiceMapper.delete(new LambdaQueryWrapper<QuestionChoice>().eq(QuestionChoice::getQuestionId,question.getId()));
//            //获取题目中所有选项
//            List<QuestionChoice> choices = question.getChoices();
//            //创建StringBuilder对象,用于拼接选项内容
//            StringBuilder stringBuilder = new StringBuilder();
//            //遍历所有选项
//            for (int i = 0; i < choices.size(); i++) {
//                //获取每一个选项
//                QuestionChoice questionChoice = choices.get(i);
//                //删除旧数据,是逻辑删除数据库中的内容不会删除,为了更新时id不冲突,创建时间和修改时间都需要同步更新,都设置为null
//                questionChoice.setId(null);
//                questionChoice.setCreateTime(null);
//                questionChoice.setUpdateTime(null);
//                //设置选项的排序
//                questionChoice.setSort(i);
//                //保存选择题的答案选型
//                questionChoiceMapper.insert(questionChoice);
//                //判断当前选项是否是正确答案
//                if (questionChoice.getIsCorrect()){
//                    stringBuilder.append((char)('A'+i));
//                    if (stringBuilder.length()>0){
//                        stringBuilder.append(",");
//                    }
//                }
//                //将正确的答案设置到answer中
//                answer.setAnswer(stringBuilder.toString());
//            }
//        }
//        //如果不是选择题,不需要进if,直接保存答案
//        questionAnswerMapper.updateById(answer);
//    }

    //    @Transactional
//    @Override
//    public boolean deleteQuestion(Long id) {
//        //删除题目之前要判断一下，当前题目是否被试卷使用
//        Long count = paperQuestionMapper.selectCount(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getQuestionId, id));
//        if (count>0){
//            throw new RuntimeException("该题目被试卷使用,不能删除");
//        }
//        //根据id删除题目信息
//        baseMapper.deleteById(id);
//        //根据id删除题目答案
//        questionAnswerMapper.delete(new LambdaQueryWrapper<QuestionAnswer>().eq(QuestionAnswer::getQuestionId,id));
//        //根据id删除题目的选项
//        questionChoiceMapper.delete(new LambdaQueryWrapper<QuestionChoice>().eq(QuestionChoice::getQuestionId,id));
//        return true;
//    }
    @Transactional
    @Override
    public boolean deleteQuestion(Long id) {
        //删除前判断,该题是否被试卷使用
        Long count = paperQuestionMapper.selectCount(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getQuestionId, id));
        if (count > 0) {
            throw new RuntimeException("该题目被试卷使用,不能删除");
        }
        //根据id删除题目信息
        baseMapper.deleteById(id);
        //根据id删除题目答案
        questionAnswerMapper.delete(new LambdaQueryWrapper<QuestionAnswer>().eq(QuestionAnswer::getQuestionId, id));
        //根据id删除题目的选项
        questionChoiceMapper.delete(new LambdaQueryWrapper<QuestionChoice>().eq(QuestionChoice::getQuestionId, id));
        return true;
    }

    @Override
    public List<Question> getPopularQuestions(Integer size) {
        //获取redis中热门题目的id
        Set<Object> redisQuestionIds = redisTemplate.opsForZSet().reverseRange("question:popular", 0, size - 1);
        //创建一个List<Question>对象,用于存储数据中所有题目
        List<Question> questionList = new ArrayList<>();
        if (redisQuestionIds !=null && redisQuestionIds.size()>0){
            //根据redis中题目的ID从数据库中获取题目信息
            redisQuestionIds.forEach(questionId->{
                //查询题目信息
                Question questionDetailsById = baseMapper.getQuestionDetailsById(Long.parseLong(questionId.toString()));
                questionList.add(questionDetailsById);
            });
        }
            //获取redis中热门题目的数量
            int redisSize = redisQuestionIds.size();
            //计算插值
            int diff = size - redisSize;
            //如果差值大于0,则从数据库中获取最新题目
            if (diff>0){
                //创建LambdaQueryWrapper对象,用于构建查询条件
                LambdaQueryWrapper<Question> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                //设置查询条件
                //以降序排列查询创建时间
                lambdaQueryWrapper.orderByDesc(Question::getCreateTime);
                //不能获取重复的redis中的题目
                lambdaQueryWrapper.notIn(redisQuestionIds.size()>0,Question::getId,redisQuestionIds);
                //在sql语句中添加limit条件
                lambdaQueryWrapper.last("limit "+ diff);
                //查询数据库中最新题目
                List<Question> questions = baseMapper.selectList(lambdaQueryWrapper);
                //添加到List<Question>对象中
                questionList.addAll(questions);
            }
            return questionList;
    }
//    @Override
//    public List<Question> getPopularQuestions(Integer size) {
//        //从redis中获取热门题目的id
//        Set<Object> redisQuestionIds = redisTemplate.opsForZSet().reverseRange("question:popular", 0, size - 1);
//        //根据redis中的id从数据库中获取题目的信息
//        List<Question> questions = baseMapper.selectList(new LambdaQueryWrapper<Question>().in(Question::getId, redisQuestionIds));
//        //将集合中的题目顺序反转
//        Collections.reverse(questions);
//        //获取redis中热门题目的数量
//        int size1 = redisQuestionIds.size();
//        //计算差值
//        int diff = size - size1;
//        if (diff > 0) {
//            //证明Redis中的热门题目数量不够，将数据库中最新的查询出来补全热门题目
//            //创建LambdaQueryWrapper对象，用于构建查询条件
//            LambdaQueryWrapper<Question> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//            //封装查询条件
//            lambdaQueryWrapper.orderByDesc(Question::getCreateTime);
//            //查询题目需要是Redis中不包含的
//            lambdaQueryWrapper.notIn(Question::getId, redisQuestionIds);
//            //在整个sql语句的最后添加limit
//            lambdaQueryWrapper.last("limit " + diff);
//            //执行带条件的查询
//            List<Question> questions1 = baseMapper.selectList(lambdaQueryWrapper);
//            //将查询出来的题目添加到redisQuestions中
//            questions.addAll(questions1);
//        }
//        System.out.println("questions = " + questions);
//        return questions;
//    }

    @Transactional
    @Override
    public int batchImportQuetions(List<QuestionImportVo> questions) {
        //检查集合是否为 null 或空
        if (CollectionUtils.isEmpty(questions)) {
            throw new RuntimeException("导入的题目不能为空");
        }
        //设置一个变量记录导入成功题目的数量
        int successCount = 0;
        //遍历导入的所有题目
        for (QuestionImportVo questionImportVo : questions) {
            //创建Question对象用于储存选项,因为类型不同,需要转换类型
            Question question = new Question();
            //使用BeanUtils工具类,将QuestionImportVo中的数据批量复制到Question对象中
            BeanUtils.copyProperties(questionImportVo, question);
            //判断是否是选择题
            if ("CHOICE".equals(questionImportVo.getType())) {
                //获取传过来文件中的选择题选项
                List<QuestionImportVo.ChoiceImportDto> choices = questionImportVo.getChoices();
                //创建List<QuestionChoice>对象用于储存选项,因为类型不同,需要转换类型
                List<QuestionChoice> questionChoices = new ArrayList<>();
                //遍历选项
                for (QuestionImportVo.ChoiceImportDto choice : choices) {
                    //创建QuestionChoice对象,存储单个选项
                    QuestionChoice questionChoice = new QuestionChoice();
                    //使用BeanUtils工具类,将QuestionImportVo.ChoiceImportDto中的数据复制到QuestionChoice对象中
                    BeanUtils.copyProperties(choice, questionChoice);
                    //将QuestionChoice对象添加到List<QuestionChoice>对象中
                    questionChoices.add(questionChoice);
                }
                //将List<QuestionChoice>对象添加到Question对象中
                question.setChoices(questionChoices);
            }
            //创建QuestionAnswer对象用于储存答案,因为类型不同,需要转换类型
            QuestionAnswer questionAnswer = new QuestionAnswer();
            //判断是否是判断题
            if ("JUDGE".equals(questionImportVo.getType())) {
                //将判断题的答案转成大写传到QuestionAnswer对象中
                questionAnswer.setAnswer(questionImportVo.getAnswer().toUpperCase());
            } else {
                //如果不是判断题直接把答案传入QuestionAnswer对象中
                questionAnswer.setAnswer(questionImportVo.getAnswer());
            }
            //将QuestionAnswer对象添加到Question对象中
            question.setAnswer(questionAnswer);
            try {
                //将Question对象添加到数据库中
                createQuestion(question);
                //没添加成功一条,成功数量加1
                successCount++;
            } catch (Exception e) {
                throw new RuntimeException("第" + successCount + 1 + "题<" + question.getTitle() + ">插入失败，失败原因：" + e.getMessage());
            }
        }
        return successCount;
    }
    @Override
    public List<QuestionImportVo> generateQuestionsByAi(AiGenerateRequestVo request) {
        //1.根据请求参数生成提示词
        String prompt = buildPrompt(request);

        //1创建WebClient对象
        WebClient webClient = WebClient.builder()
                //设置大模型API的服务地址。
                .baseUrl(kimiProperties.getBaseUrl())
                //设置请求数据的类型是JSON格式
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                //设置apiKey
                .defaultHeader(HttpHeaders.AUTHORIZATION, kimiProperties.getApiKey())
                .build();
        //2.调用Kimi的API返回AI生成的结果
        String content = callKimiAi(prompt,webClient);
        int startIndex = content.indexOf("```json");
        int endIndex = content.lastIndexOf("```");
        //保证有数据，且下标正确！
        if (startIndex != -1 && endIndex != -1 && startIndex < endIndex) {
            //获取真正结果
            String realResult = content.substring(startIndex+7,endIndex);
            System.out.println("realResult = " + realResult);
            JSONObject jsonObject = JSONObject.parseObject(realResult);
            JSONArray questions = jsonObject.getJSONArray("questions");
            List<QuestionImportVo> questionImportVoList = new ArrayList<>();
            for (int i = 0; i < questions.size(); i++) {
                //获取对象
                JSONObject questionJson = questions.getJSONObject(i);
                QuestionImportVo questionImportVo = new QuestionImportVo();
                questionImportVo.setTitle(questionJson.getString("title"));
                questionImportVo.setType(questionJson.getString("type"));
                questionImportVo.setMulti(questionJson.getBoolean("multi"));
                questionImportVo.setDifficulty(questionJson.getString("difficulty"));
                questionImportVo.setScore(questionJson.getInteger("score"));
                questionImportVo.setAnalysis(questionJson.getString("analysis"));
                questionImportVo.setCategoryId(request.getCategoryId());

                //选择题处理选项
                if ("CHOICE".equals(questionImportVo.getType())) {
                    JSONArray choices = questionJson.getJSONArray("choices");
                    List<QuestionImportVo.ChoiceImportDto> choiceImportDtoList = new ArrayList<>(choices.size());
                    for (int i1 = 0; i1 < choices.size(); i1++) {
                        JSONObject choicesJSONObject = choices.getJSONObject(i1);
                        QuestionImportVo.ChoiceImportDto choiceImportDto = new QuestionImportVo.ChoiceImportDto();
                        choiceImportDto.setContent(choicesJSONObject.getString("content"));
                        choiceImportDto.setIsCorrect(choicesJSONObject.getBoolean("isCorrect"));
                        choiceImportDto.setSort(choicesJSONObject.getInteger("sort"));
                        choiceImportDtoList.add(choiceImportDto);
                    }
                    questionImportVo.setChoices(choiceImportDtoList);
                }
                //答案 [判断题！ TRUE |FALSE  false true  f  t 是 否]
                questionImportVo.setAnswer(questionJson.getString("answer"));
                questionImportVoList.add(questionImportVo);
            }
            return questionImportVoList;
        }
        throw new RuntimeException("ai生成题目json数据结构错误，无法正常解析！数据为：%s".formatted(content));
    }

    @Override
    public String buildPrompt(AiGenerateRequestVo request) {
        StringBuilder prompt = new StringBuilder();

        prompt.append("请为我生成").append(request.getCount()).append("道关于【")
                .append(request.getTopic()).append("】的题目。\n\n");

        prompt.append("要求：\n");

        // 题目类型要求
        if (request.getTypes() != null && !request.getTypes().isEmpty()) {
            List<String> typeList = Arrays.asList(request.getTypes().split(","));
            prompt.append("- 题目类型：");
            for (String type : typeList) {
                switch (type.trim()) {
                    case "CHOICE":
                        prompt.append("选择题");
                        if (request.getIncludeMultiple() != null && request.getIncludeMultiple()) {
                            prompt.append("(包含单选和多选)");
                        }
                        prompt.append(" ");
                        break;
                    case "JUDGE":
                        prompt.append("判断题（**重要：确保正确答案和错误答案的数量大致平衡，不要全部都是正确或错误**） ");
                        break;
                    case "TEXT":
                        prompt.append("简答题 ");
                        break;
                }
            }
            prompt.append("\n");
        }

        // 难度要求
        if (request.getDifficulty() != null) {
            String difficultyText = switch (request.getDifficulty()) {
                case "EASY" -> "简单";
                case "MEDIUM" -> "中等";
                case "HARD" -> "困难";
                default -> "中等";
            };
            prompt.append("- 难度等级：").append(difficultyText).append("\n");
        }

        // 额外要求
        if (request.getRequirements() != null && !request.getRequirements().isEmpty()) {
            prompt.append("- 特殊要求：").append(request.getRequirements()).append("\n");
        }

        // 判断题特别要求
        if (request.getTypes() != null && request.getTypes().contains("JUDGE")) {
            prompt.append("- **判断题特别要求**：\n");
            prompt.append("  * 确保生成的判断题中，正确答案(TRUE)和错误答案(FALSE)的数量尽量平衡\n");
            prompt.append("  * 不要所有判断题都是正确的或都是错误的\n");
            prompt.append("  * 错误的陈述应该是常见的误解或容易混淆的概念\n");
            prompt.append("  * 正确的陈述应该是重要的基础知识点\n");
        }

        prompt.append("\n请严格按照以下JSON格式返回，不要包含任何其他文字：\n");
        prompt.append("```json\n");
        prompt.append("{\n");
        prompt.append("  \"questions\": [\n");
        prompt.append("    {\n");
        prompt.append("      \"title\": \"题目内容\",\n");
        prompt.append("      \"type\": \"CHOICE|JUDGE|TEXT\",\n");
        prompt.append("      \"multi\": true/false,\n");
        prompt.append("      \"difficulty\": \"EASY|MEDIUM|HARD\",\n");
        prompt.append("      \"score\": 5,\n");
        prompt.append("      \"choices\": [\n");
        prompt.append("        {\"content\": \"选项内容\", \"isCorrect\": true/false, \"sort\": 1}\n");
        prompt.append("      ],\n");
        prompt.append("      \"answer\": \"TRUE或FALSE(判断题专用)|文本答案(简答题专用)\",\n");
        prompt.append("      \"analysis\": \"题目解析\"\n");
        prompt.append("    }\n");
        prompt.append("  ]\n");
        prompt.append("}\n");
        prompt.append("```\n\n");

        prompt.append("注意：\n");
        prompt.append("1. 选择题必须有choices数组，判断题和简答题设置answer字段\n");
        prompt.append("2. 多选题的multi字段设为true，单选题设为false\n");
        prompt.append("3. **判断题的answer字段只能是\"TRUE\"或\"FALSE\"，请确保答案分布合理**\n");
        prompt.append("4. 每道题都要有详细的解析\n");
        prompt.append("5. 题目要有实际价值，贴近实际应用场景\n");
        prompt.append("6. 严格按照JSON格式返回，确保可以正确解析\n");

        // 如果只生成判断题，额外强调答案平衡
        if (request.getTypes() != null && request.getTypes().equals("JUDGE") && request.getCount() > 1) {
            prompt.append("7. **判断题答案分布要求**：在").append(request.getCount()).append("道判断题中，");
            int halfCount = request.getCount() / 2;
            if (request.getCount() % 2 == 0) {
                prompt.append("请生成").append(halfCount).append("道正确(TRUE)和").append(halfCount).append("道错误(FALSE)的题目");
            } else {
                prompt.append("请生成约").append(halfCount).append("-").append(halfCount + 1).append("道正确(TRUE)和约").append(halfCount).append("-").append(halfCount + 1).append("道错误(FALSE)的题目");
            }
        }
        return prompt.toString();
    }

    //给题目设置答案和选项的方法
    private void fillAnswerAndChoices(List<Question> pageQuestionList) {
        //获取所有题目的ID
        List<Long> questionIds = pageQuestionList.stream().map(Question::getId).collect(Collectors.toList());
        //根据题目ID查询所有的答案
        LambdaQueryWrapper<QuestionAnswer> questionAnswerLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //封装查询条件
        questionAnswerLambdaQueryWrapper.in(QuestionAnswer::getQuestionId, questionIds);
        //调用QuestionAnswerMapper的带条件查询的方法
        List<QuestionAnswer> questionAnswers = questionAnswerMapper.selectList(questionAnswerLambdaQueryWrapper);
        //将答案以题目ID为key，答案列表为value，转换为Map
        Map<Long, QuestionAnswer> questionAnswerMap = questionAnswers.stream().collect(Collectors.toMap(QuestionAnswer::getQuestionId, q -> q));
        //遍历所有的题目
        pageQuestionList.forEach(question -> {
            //根据题目ID获取当前题目的答案
            QuestionAnswer questionAnswer = questionAnswerMap.get(question.getId());
            //给题目设置答案
            question.setAnswer(questionAnswer);
            //判断当前题是不是选择题或判断题
            if ("CHOICE".equals(question.getType()) || "JUDGE".equals(question.getType())) {
                //根据题目id获取所有的选项
                //创建LambdaQueryWrapper对象，用于构建查询条件
                LambdaQueryWrapper<QuestionChoice> questionChoiceLambdaQueryWrapper = new LambdaQueryWrapper<>();
                //封装查询条件
                questionChoiceLambdaQueryWrapper.eq(QuestionChoice::getQuestionId, question.getId());
                //调用QuestionChoiceMapper的带条件查询的方法
                List<QuestionChoice> questionChoices = questionChoiceMapper.selectList(questionChoiceLambdaQueryWrapper);
                //排序
                questionChoices.sort((o1, o2) -> o1.getSort().compareTo(o2.getSort()));
                //将选项设置到题目中
                question.setChoices(questionChoices);
            }
        });
    }

    //调用Kimi的方法
    public String callKimiAi(String prompt,WebClient webClient) {

        int maxTry = 3; //最多重试3次
        for (int i = 1; i <= 3; i++) {
            try {
                //请求体的内容 https://platform.moonshot.cn/docs/api/chat#%E8%AF%B7%E6%B1%82%E5%86%85%E5%AE%B9
                Map<String, String> userMap = new HashMap<>();
                userMap.put("role", "user");
                userMap.put("content", prompt); //提示词
                List<Map> messagesList = new ArrayList<>();
                messagesList.add(userMap);

                Map<String, Object> requestBody = new HashMap<>();
                requestBody.put("model", kimiProperties.getModel());
                requestBody.put("messages", messagesList);
                requestBody.put("temperature", kimiProperties.getTemperature());
                requestBody.put("max_tokens", kimiProperties.getMaxTokens());

                //2. 发起网络请求调用
                Mono<String> stringMono = webClient.post()
                        .bodyValue(requestBody)
                        .retrieve() //准备了
                        .bodyToMono(String.class)
                        .timeout(Duration.ofSeconds(100));

                //webClient异步请求
                //同步
                String result = stringMono.block();
                //jackson工具！ JsonObject JsonArray
                JSONObject resultJsonObject = JSONObject.parseObject(result);

                //错误结果：https://platform.moonshot.cn/docs/api/chat#错误说明
                if (resultJsonObject.containsKey("error")) {
                    throw new RuntimeException("访问错误了，错误信息为:" +
                            resultJsonObject.getJSONObject("error").getString("message"));
                }
                //正确结果：https://platform.moonshot.cn/docs/api/chat#%E8%BF%94%E5%9B%9E%E5%86%85%E5%AE%B9
                //获取返回内容content
                // ```json  ```
                String content = resultJsonObject.getJSONArray("choices").getJSONObject(0).
                        getJSONObject("message").getString("content");
                log.debug("调用kimi返回的结果为：{}", content);

                if (content == null || content.isEmpty()) {
                    throw new RuntimeException("调用成功！但是没有返回结果！！");
                }
                return content;
            } catch (Exception e) {
                //打印信息
                log.debug("第{}次尝试调用失败了！", i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    throw new RuntimeException(ex);
                }
                //                第几次尝试 i 次！
                if (i == maxTry) {
                    e.printStackTrace();
                    throw new RuntimeException("已经重试3次！依然失败！请稍后再试！！");
                }
            }
        }
        throw new RuntimeException("已经重试3次！依然失败！请稍后再试！！");
    }
}

//    @Override
//    public int batchImportQuetions(List<QuestionImportVo> questions) {
//        //检查集合是否为 null 或空
//        if (CollectionUtils.isEmpty(questions)){
//            throw new RuntimeException("导入的题目不能为空");
//        }
//        //设置一个变量记录导入成功题目的数量
//        int successCount = 0;
//        //遍历所有导入的题
//        for (QuestionImportVo questionImportVo : questions) {
//            //创建Question对象用于储存选项,因为类型不同,需要转换类型
//            Question question = new Question();
//            //使用BeanUtils工具类,将QuestionImportVo中的数据复制到Question对象中
//            BeanUtils.copyProperties(questionImportVo,question);
//            //判断是否是选择题
//            if ("CHOICE".equals(questionImportVo.getType())){
//                //获取所有选项
//                List<QuestionImportVo.ChoiceImportDto> choices = questionImportVo.getChoices();
//                //创建一个List<QuestionChoice>对象用于储存选项,因为类型不同,需要转换类型
//                List<QuestionChoice> questionChoices = new ArrayList<>();
//                //遍历每一个选项
//                for (QuestionImportVo.ChoiceImportDto choice : choices) {
//                    //创建QuestionChoice对象用于储存选项
//                    QuestionChoice questionChoice = new QuestionChoice();
//                    //使用BeanUtils工具类,将QuestionImportVo.ChoiceImportDto中的数据复制到QuestionChoice对象中
//                    BeanUtils.copyProperties(choice,questionChoice);
//                    //将QuestionChoice对象添加到List<QuestionChoice>中
//                    questionChoices.add(questionChoice);
//                }
//                //将List<QuestionChoice>对象保存到question对象中
//                question.setChoices(questionChoices);
//            }
//            //创建一个QuestionAnswer对象
//            QuestionAnswer questionAnswer = new QuestionAnswer();
//            //判断是否是判断题，如果是判断题，将true或false转换为大写
//            if ("JUDGE".equals(questionImportVo.getType())){
//                //将questionAnswer对象中判断题的答案转换为大写
//                questionAnswer.setAnswer(questionImportVo.getAnswer().toUpperCase());
//            }else{
//                //如果不是判断题questionAnswer对象中的答案直接保存到questionAnswer对象中
//                questionAnswer.setAnswer(questionImportVo.getAnswer());
//            }
//            //将QuestionAnswer对象保存到question对象中
//            question.setAnswer(questionAnswer);
//            try {
//                //将题目插入到数据库
//                createQuestion(question);
//                //如果插入成功，successCount++
//                successCount++;
//            } catch (Exception e) {
//                throw new RuntimeException("第"+successCount+1+"题<"+question.getTitle()+">插入失败，失败原因："+e.getMessage());
//            }
//        }
//        return successCount;
//    }
//}